package com.iplant.wms.serviceImpl;

import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.RetCode;
import com.iplant.wms.service.WMSService;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.wms.service.basicenum.bill.WMSOutboundOrderStatus;
import com.iplant.wms.service.basicenum.wms.WMSSalesDeliveryStatus;
import com.iplant.wms.service.basicenum.wms.WMSStockRecordType;
import com.iplant.wms.service.po.asn.WMSReceiveBill;
import com.iplant.wms.service.po.bill.WMSOutboundOrder;
import com.iplant.wms.service.po.bill.WMSOutboundOrderItem;
import com.iplant.wms.service.po.bill.WMSSalesDelivery;
import com.iplant.wms.service.po.bill.WMSSalesDeliveryItem;
import com.iplant.wms.service.po.mrp.MRPDelivery;
import com.iplant.wms.service.po.wms.*;
import com.iplant.basic.serviceImpl.BMSServiceImpl;
import com.iplant.wms.serviceImpl.dao.bill.WMSOutboundOrderDAO;
import com.iplant.wms.serviceImpl.dao.bill.WMSOutboundOrderItemDAO;
import com.iplant.wms.serviceImpl.dao.asn.WMSReceiveBillItemDAO;
import com.iplant.wms.serviceImpl.dao.mrp.MRPDeliveryDAO;
import com.iplant.wms.serviceImpl.dao.wms.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xiuto
 */
@Service
public class WMSServiceImpl implements WMSService {
    private static Logger logger = LoggerFactory.getLogger(BMSServiceImpl.class);

    public WMSServiceImpl() {
        // TODO Auto-generated constructor stub
    }

    private static WMSService Instance = null;

    public static WMSService getInstance() {
        if (Instance == null) {
            Instance = new WMSServiceImpl();
        }

        return Instance;
    }


    @Override
    public ServiceResult<Integer> WMS_UpdateResource(BMSEmployee wLoginUser, WMSResource wResource) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            WMSResourceDAO.getInstance().UpdatePo(wLoginUser, wResource, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_DeleteResource(BMSEmployee wLoginUser, WMSResource wResource) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            WMSResourceDAO.getInstance().DeletePO(wLoginUser, wResource, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSResource> WMS_QueryResource(BMSEmployee wLoginUser, int wID) {
        ServiceResult<WMSResource> wResult = new ServiceResult<WMSResource>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            wResult.Result = WMSResourceDAO.getInstance().SelectPO(wLoginUser, wID,"", wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSResource>> WMS_QueryResourceList(BMSEmployee wLoginUser, int wStoreID, int wStoreRegionID,
                                                                  int wStoreAreaID, int wStoreShelfID, int wStoreStationID, List<Integer> wStationID,
                                                                  List<Integer> wMaterialID, Pagination wPagination) {
        ServiceResult<List<WMSResource>> wResult = new ServiceResult<List<WMSResource>>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            wResult.Result = WMSResourceDAO.getInstance().WMS_QueryResourceList(wLoginUser, wStoreID,
                    wStoreRegionID, wStoreAreaID, wStoreShelfID, wStoreStationID, wStationID, wMaterialID, wPagination, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }


    @Override
    public ServiceResult<Integer> WMS_UpdateStockSafe(BMSEmployee wLoginUser, WMSStockSafe wStockSafe) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            WMSStockSafeDAO.getInstance().WMS_UpdateStockSafe(wLoginUser, wStockSafe, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_DeleteStockSafe(BMSEmployee wLoginUser, WMSStockSafe wStockSafe) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            WMSStockSafeDAO.getInstance().DeletePO(wLoginUser, wStockSafe, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_ActiveStockSafe(BMSEmployee wLoginUser, WMSStockSafe wStockSafe, int wActive) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            WMSStockSafeDAO.getInstance().WMS_ActiveStockSafe(wLoginUser, wStockSafe, wActive, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSStockSafe> WMS_QueryStockSafe(BMSEmployee wLoginUser, int wID, String wCode) {
        ServiceResult<WMSStockSafe> wResult = new ServiceResult<WMSStockSafe>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            wResult.Result = WMSStockSafeDAO.getInstance().WMS_QueryStockSafe(wLoginUser, wID, wCode, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSStockSafe>> WMS_QueryStockSafeList(
            BMSEmployee wLoginUser, int wFactoryID, int wStoreRegionID, int wStoreID, String wStoreCode,
            String wStoreName, int wStoreAreaID, String wStoreAreaCode, String wStoreAreaName, int wMaterialID,
            String wMaterialCode, String wMaterialName, String wName, int wActive, Pagination wPagination) {
        ServiceResult<List<WMSStockSafe>> wResult = new ServiceResult<List<WMSStockSafe>>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            wResult.Result = WMSStockSafeDAO.getInstance().WMS_QueryStockSafeList(wLoginUser, wFactoryID,
                    wStoreRegionID, wStoreID, wStoreCode, wStoreName, wStoreAreaID, wStoreAreaCode, wStoreAreaName,
                    wMaterialID, wMaterialCode, wMaterialName, wName, wActive, wPagination, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_UpdateStockAlarm(BMSEmployee wLoginUser, WMSStockAlarm wStockAlarm) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            WMSStockAlarmDAO.getInstance().WMS_UpdateStockAlarm(wLoginUser, wStockAlarm, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_DeleteStockAlarm(BMSEmployee wLoginUser, WMSStockAlarm wStockAlarm) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            WMSStockAlarmDAO.getInstance().DeletePO(wLoginUser, wStockAlarm, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_ActiveStockAlarm(BMSEmployee wLoginUser, WMSStockAlarm wStockAlarm, int wActive) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            WMSStockAlarmDAO.getInstance().WMS_ActiveStockAlarm(wLoginUser, wStockAlarm, wActive, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSStockAlarm> WMS_QueryStockAlarm(BMSEmployee wLoginUser, int wID, String wCode) {
        ServiceResult<WMSStockAlarm> wResult = new ServiceResult<WMSStockAlarm>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            wResult.Result = WMSStockAlarmDAO.getInstance().WMS_QueryStockAlarm(wLoginUser, wID, wCode, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSStockAlarm>> WMS_QueryStockAlarmList(
            BMSEmployee wLoginUser, int wFactoryID, int wStoreRegionID, int wStoreID, String wStoreCode,
            String wStoreName, int wStoreAreaID, String wStoreAreaCode, String wStoreAreaName, int wMaterialID,
            String wMaterialCode, String wMaterialName, String wName, int wActive, Calendar wStartTime,
            Calendar wEndTime, Pagination wPagination) {
        ServiceResult<List<WMSStockAlarm>> wResult = new ServiceResult<List<WMSStockAlarm>>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            wResult.Result = WMSStockAlarmDAO.getInstance().WMS_QueryStockAlarmList(wLoginUser, wFactoryID,
                    wStoreRegionID, wStoreID, wStoreCode, wStoreName, wStoreAreaID, wStoreAreaCode, wStoreAreaName,
                    wMaterialID, wMaterialCode, wMaterialName, wName, wActive, wStartTime, wEndTime, wPagination,
                    wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_UpdateStockRecord(BMSEmployee wLoginUser, WMSStockRecord wStockRecord) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            WMSStockRecordDAO.getInstance().UpdatePo(wLoginUser, wStockRecord, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_DeleteStockRecord(BMSEmployee wLoginUser, WMSStockRecord wStockRecord) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            WMSStockRecordDAO.getInstance().DeletePO(wLoginUser, wStockRecord, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_ActiveStockRecord(
            BMSEmployee wLoginUser, WMSStockRecord wStockRecord, int wActive) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            WMSStockRecordDAO.getInstance().ActivePO(wLoginUser, wStockRecord, wActive, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }


    @Override
    public ServiceResult<List<WMSStock>> WMS_QueryStockCountList(BMSEmployee wLoginUser, int wFactoryID, int wStoreID, int wStoreRegionID, int wStoreAreaID,
                                                                 int wStoreShelfID, int wStoreStationID, List<Integer> wMaterialIDList, int wBatchRecordID, String wBatchRecordCode, String wProjectNo,
                                                                 int wCustomerID, int wSupplierID, int wStockTypeID, int wStockStatus, int wHasItem, Pagination wPagination) {
        ServiceResult<List<WMSStock>> wResult = new ServiceResult<List<WMSStock>>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            wResult.Result = WMSStockRecordDAO.getInstance().WMS_QueryStockCountList(wLoginUser, wFactoryID,
                    wStoreID, wStoreRegionID, wStoreAreaID, wStoreShelfID, wStoreStationID, wMaterialIDList,
                    wBatchRecordID, wBatchRecordCode, wProjectNo, wCustomerID, wSupplierID, wStockTypeID, wStockStatus, wHasItem, wPagination, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_UpdateStockFreeze(BMSEmployee wLoginUser, WMSStockFreeze wStockFreeze) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            WMSStockFreezeDAO.getInstance().WMS_UpdateStockFreeze(wLoginUser, wStockFreeze, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_DeleteStockFreeze(BMSEmployee wLoginUser, WMSStockFreeze wStockFreeze) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            WMSStockFreezeDAO.getInstance().DeletePO(wLoginUser, wStockFreeze, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_ActiveStockFreeze(
            BMSEmployee wLoginUser, WMSStockFreeze wStockFreeze, int wActive) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            WMSStockFreezeDAO.getInstance().WMS_ActiveStockFreeze(wLoginUser, wStockFreeze, wActive, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSStockFreeze>> WMS_QueryStockFreezeList(
            BMSEmployee wLoginUser, int wFactoryID, int wStoreRegionID, int wStoreID, int wStoreAreaID,
            int wStoreShelfID, int wStoreStationID, int wMaterialID, String wMaterialCode, String wMaterialName,
            String wProjectNo, String wBatchNo, int wActive, Calendar wStartTime, Calendar wEndTime,
            Pagination wPagination) {
        ServiceResult<List<WMSStockFreeze>> wResult = new ServiceResult<List<WMSStockFreeze>>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            wResult.Result = WMSStockFreezeDAO.getInstance().WMS_QueryStockFreezeList(wLoginUser, wFactoryID,
                    wStoreRegionID, wStoreID, wStoreAreaID, wStoreShelfID, wStoreStationID, wMaterialID, wMaterialCode,
                    wMaterialName, wProjectNo, wBatchNo, wActive, wStartTime, wEndTime, wPagination, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<MRPDelivery>> MRP_SelectDeliveryListByDate(BMSEmployee wLoginUser, Calendar wStartDate, Calendar wEndDate, Pagination wPagination) {
        ServiceResult<List<MRPDelivery>> wResult = new ServiceResult<List<MRPDelivery>>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            wErrorCode.set(0);
            wResult.Result = MRPDeliveryDAO.getInstance().MRP_SelectDeliveryListByDate(wLoginUser, wStartDate, wEndDate, wPagination, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_ApplyForShipment(BMSEmployee wLoginUser, int wWMSSalesDeliveryID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSSalesDelivery wWMSSalesDelivery = WMSSalesDeliveryDAO.getInstance().SelectPO(wLoginUser, wWMSSalesDeliveryID, "",
                    wErrorCode);
            if (wWMSSalesDelivery == null || wWMSSalesDelivery.ID <= 0) {
                wResult.FaultCode += "提示：发货单不存在!";
                return wResult;
            }

            if (wWMSSalesDelivery.Status != WMSSalesDeliveryStatus.Saved.getValue()) {
                wResult.FaultCode += "提示：只能提交“保存”状态的数据!";
                return wResult;
            }

            wWMSSalesDelivery.Status = WMSSalesDeliveryStatus.ToBeSorted.getValue();
            wWMSSalesDelivery.EditorID = wLoginUser.ID;
            wWMSSalesDelivery.EditTime = Calendar.getInstance();
            wResult.Result = WMSSalesDeliveryDAO.getInstance().UpdatePo(wLoginUser, wWMSSalesDelivery, wErrorCode);

            wResult.AddFaultCode(wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public synchronized ServiceResult<WMSSalesDelivery> WMS_UpdateSalesDelivery(BMSEmployee wLoginUser,
                                                                                WMSSalesDelivery wWMSSalesDelivery) {
        ServiceResult<WMSSalesDelivery> wResult = new ServiceResult<>();
        wResult.Result = new WMSSalesDelivery();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wWMSSalesDelivery.ID > 0) {
                if (wWMSSalesDelivery.Status != WMSSalesDeliveryStatus.Saved.getValue()) {
                    wResult.FaultCode += "提示：只能修改“保存”状态的数据!";
                    return wResult;
                }
            } else {
                Calendar wBaseTime = Calendar.getInstance();
                wBaseTime.set(2000, 0, 1, 0, 0, 0);
                wWMSSalesDelivery.SenderTime = wBaseTime;
                wWMSSalesDelivery.Status = (wWMSSalesDelivery.Status == 0) ? WMSSalesDeliveryStatus.Saved.getValue() : wWMSSalesDelivery.Status;
            }
            wWMSSalesDelivery.setUserInfo(wLoginUser);
            WMSSalesDeliveryDAO.getInstance().UpdatePo(wLoginUser, wWMSSalesDelivery, wErrorCode);

            if (wErrorCode.Result != 0) {
                wResult.AddFaultCode(wErrorCode);
                return wResult;
            }
            if (wWMSSalesDelivery.ID > 0) {
                for (WMSSalesDeliveryItem wWMSSalesDeliveryItem : wWMSSalesDelivery.ItemList) {
                    wWMSSalesDeliveryItem.SalesDeliveryID = wWMSSalesDelivery.ID;
                }
                WMSSalesDeliveryItemDAO.getInstance().UpdatePoList(wLoginUser, wWMSSalesDelivery.ItemList,
                        wErrorCode);
            }
            wResult.Result = wWMSSalesDelivery;

            wResult.AddFaultCode(wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }


    @Override
    public ServiceResult<WMSSalesDelivery> WMS_SalesDeliveryStartSorting(BMSEmployee wLoginUser,
                                                                         WMSSalesDelivery wWMSSalesDelivery) {
        ServiceResult<WMSSalesDelivery> wResult = new ServiceResult<>();
        wResult.Result = new WMSSalesDelivery();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);


            WMSOutboundOrder wWMSOutboundOrder = WMSOutboundOrderDAO.getInstance()
                    .WMS_CreateFromSalesDelivery(wLoginUser, wWMSSalesDelivery, wErrorCode);

            if (wErrorCode.Result != 0) {
                wResult.AddFaultCode(wErrorCode);
                return wResult;
            }
            wWMSOutboundOrder.Type = WMSStockRecordType.SalesOutOfStock.getValue();
            WMSOutboundOrderDAO.getInstance().UpdatePo(wLoginUser, wWMSOutboundOrder,
                    wErrorCode);
            if (wErrorCode.Result != 0) {
                wResult.AddFaultCode(wErrorCode);
                return wResult;
            }
            if (wWMSOutboundOrder.ID > 0) {
                wWMSSalesDelivery.SortingSerialNumber = wWMSOutboundOrder.Code;
                wWMSSalesDelivery.Status = WMSSalesDeliveryStatus.Picking.getValue();

                WMSSalesDeliveryDAO.getInstance().UpdatePo(wLoginUser, wWMSSalesDelivery, wErrorCode);
                wResult.Result = wWMSSalesDelivery;
            }
            wResult.AddFaultCode(wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSSalesDelivery> WMS_SalesDeliveryFinishSorting(BMSEmployee wLoginUser,
                                                                          WMSSalesDelivery wWMSSalesDelivery) {
        ServiceResult<WMSSalesDelivery> wResult = new ServiceResult<>();
        wResult.Result = new WMSSalesDelivery();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wWMSSalesDelivery.Status = WMSSalesDeliveryStatus.PickingDone.getValue();
            WMSSalesDeliveryDAO.getInstance().UpdatePo(wLoginUser, wWMSSalesDelivery, wErrorCode);
            wResult.Result = wWMSSalesDelivery;

            wResult.AddFaultCode(wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSSalesDelivery> WMS_SalesDeliveryConfirmOutOfStock(BMSEmployee wLoginUser,
                                                                              WMSSalesDelivery wWMSSalesDelivery) {
        ServiceResult<WMSSalesDelivery> wResult = new ServiceResult<>();
        wResult.Result = new WMSSalesDelivery();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wWMSSalesDelivery == null || wWMSSalesDelivery.ID <= 0) {
                wResult.FaultCode += RetCode.SERVER_RST_ERROR_OUT;
                return wResult;
            }

            if (StringUtils.isEmpty(wWMSSalesDelivery.ShipmentNumber)) {
                wResult.FaultCode += "提示：物流单号未填写!";
                return wResult;
            }

            wWMSSalesDelivery.ItemList = WMSSalesDeliveryItemDAO.getInstance().WMS_SelectSalesDeliveryItemList(wLoginUser,
                    wWMSSalesDelivery.ID, -1, Pagination.getMaxSize(), wErrorCode);

            if (wErrorCode.Result != 0) {
                wResult.AddFaultCode(wErrorCode);
                return wResult;
            }

            wWMSSalesDelivery.Status = WMSSalesDeliveryStatus.AllShipped.getValue();
            wWMSSalesDelivery.SenderID = wLoginUser.ID;
            wWMSSalesDelivery.SenderTime = Calendar.getInstance();
            wWMSSalesDelivery.SenderName = wLoginUser.Name;
            WMSSalesDeliveryDAO.getInstance().UpdatePo(wLoginUser, wWMSSalesDelivery, wErrorCode);
            wResult.Result = wWMSSalesDelivery;

            wResult.AddFaultCode(wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSSalesDelivery> WMS_SalesDeliverySubmitInvoice(BMSEmployee wLoginUser,
                                                                          int wWMSSalesDeliveryID) {
        ServiceResult<WMSSalesDelivery> wResult = new ServiceResult<>();
        wResult.Result = new WMSSalesDelivery();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSSalesDelivery wWMSSalesDelivery = WMSSalesDeliveryDAO.getInstance().SelectPO(wLoginUser, wWMSSalesDeliveryID, "",
                    wErrorCode);
            wResult = WMS_SalesDeliveryFinishSorting(wLoginUser, wWMSSalesDelivery);

            wResult.AddFaultCode(wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }


    @Override
    public ServiceResult<List<WMSStockRecord>> WMS_QueryStockInfoByItemID(BMSEmployee wLoginUser,
                                                                          int wSalesDeliveryItemID) {
        ServiceResult<List<WMSStockRecord>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSSalesDeliveryItem wWMSSalesDeliveryItem =
                    WMSSalesDeliveryItemDAO.getInstance().SelectPO(wLoginUser, wSalesDeliveryItemID, "", wErrorCode);
            if (wErrorCode.Result != 0) {
                wResult.AddFaultCode(wErrorCode);
                return wResult;
            }

            if (wWMSSalesDeliveryItem == null || wWMSSalesDeliveryItem.ID == 0) {
                return wResult;
            }

            wResult.Result = WMSStockRecordDAO.getInstance().WMS_QueryStockRecordList(wLoginUser,
                    wWMSSalesDeliveryItem.FactoryID, wWMSSalesDeliveryItem.StoreID, StringUtils.parseListArgs(wWMSSalesDeliveryItem.MaterialID)
                    , Pagination.getMaxSize(), wErrorCode);


            //按照仓库、库位、物料、批次排序
            wResult.Result.sort(Comparator.comparing(WMSStockRecord::getStoreID)
                    .thenComparing(WMSStockRecord::getStoreRegionID)
                    .thenComparing(WMSStockRecord::getStoreAreaID)
                    .thenComparing(WMSStockRecord::getStoreShelfID)
                    .thenComparing(WMSStockRecord::getStoreStationID)
                    .thenComparing(WMSStockRecord::getMaterialID));

            wResult.FaultCode += ExceptionTypes.getEnumType(wErrorCode.get()).getLabel();
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_DeliveryOutWarehouse(BMSEmployee wLoginUser, WMSOutboundOrder wWMSOutboundOrder) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            for (WMSOutboundOrderItem wWMSOutboundOrderItem : wWMSOutboundOrder.ItemList) {
                if (StringUtils.isEmpty(wWMSOutboundOrderItem.TrackingNumber)) {
                    wResult.FaultCode += StringUtils.Format("提示：【{0}-{1}】未填写快递单号，无法发货出库!",
                            wWMSOutboundOrderItem.MaterialCode, wWMSOutboundOrderItem.MaterialName);
                    return wResult;
                }
            }

            wWMSOutboundOrder = WMSOutboundOrderDAO.getInstance().SelectPO(wLoginUser,
                    wWMSOutboundOrder.ID, "", wErrorCode);
            if (wWMSOutboundOrder.Status != WMSOutboundOrderStatus.PickingDone.getValue()) {
                wResult.FaultCode += "提示：该出库单未拣货完成，无法发货出库!";
                return wResult;
            }

            //销售单出库
            List<WMSStockOperateRecord> wWMSStockRecordList = new ArrayList<>();
            for (WMSOutboundOrderItem wWMSOutboundOrderItem : wWMSOutboundOrder.ItemList) {

                if (wWMSOutboundOrderItem == null || wWMSOutboundOrderItem.ID <= 0 || wWMSOutboundOrderItem.StoreStationID <= 0
                        || wWMSOutboundOrderItem.BatchRecordID <= 0)
                    continue;

                WMSStockOperateRecord wStockOperateRecord = new WMSStockOperateRecord();
                wStockOperateRecord.setStockRecord(wWMSOutboundOrderItem, wWMSOutboundOrder.Type);
                wStockOperateRecord.setUserInfo(wLoginUser);
                wStockOperateRecord.RecordType = WMSStockRecordType.SalesOutOfStock.getValue();
                wStockOperateRecord.MaterialNum = wWMSOutboundOrderItem.FQTY;

                WMSStockRecordOperateDAO.getInstance().WMS_UpdateStockRecordOperate(wLoginUser, wStockOperateRecord, wErrorCode);
                if (wErrorCode.Result != 0) {
                    wResult.AddFaultCode(wErrorCode);
                }
                if (wStockOperateRecord != null && wStockOperateRecord.ID > 0) {
                    wWMSOutboundOrderItem.StockOperateRecordID = wStockOperateRecord.ID;
                    wWMSOutboundOrderItem.StockRecordID = wStockOperateRecord.RecordID;
                }
                wWMSStockRecordList.add(wStockOperateRecord);
            }

            if (StringUtils.isNotEmpty(wResult.FaultCode)) {

                return wResult;
            }

            //销售出库单状态维护
            wWMSOutboundOrder.Status = WMSOutboundOrderStatus.OutOfStock.getValue();
            wWMSOutboundOrder.EditorID = wLoginUser.ID;
            wWMSOutboundOrder.EditTime = Calendar.getInstance();
            wResult.Result = WMSOutboundOrderDAO.getInstance().UpdatePo(wLoginUser, wWMSOutboundOrder, wErrorCode);

            //维护发货单状态
            WMSSalesDelivery wWMSSalesDelivery =
                    WMSSalesDeliveryDAO.getInstance().SelectPO(wLoginUser, wWMSOutboundOrder.SalesDeliveryID, "", wErrorCode);
            boolean wIsPartSend = false;
            for (WMSSalesDeliveryItem wWMSSalesDeliveryItem : wWMSSalesDelivery.ItemList) {
                double wRealFQTY = 0;
                List<WMSOutboundOrderItem> wIList =
                        wWMSOutboundOrder.ItemList.stream().filter(p -> p.MaterialID == wWMSSalesDeliveryItem.MaterialID).collect(Collectors.toList());
                for (WMSOutboundOrderItem wWMSOutboundOrderItem : wIList) {
                    if (wWMSOutboundOrderItem.StoreStationID <= 0 || wWMSOutboundOrderItem.BatchRecordID <= 0 || wWMSOutboundOrderItem.StockOperateRecordID <= 0)
                        continue;
                    wRealFQTY += wWMSOutboundOrderItem.FQTY;
                }
                if (wRealFQTY < wWMSSalesDeliveryItem.FQTY) {
                    wIsPartSend = true;
                }
            }
            if (wIsPartSend) {
                wWMSSalesDelivery.Status = WMSSalesDeliveryStatus.PartiallyShipped.getValue();
            } else {
                wWMSSalesDelivery.Status = WMSSalesDeliveryStatus.AllShipped.getValue();
            }
            wWMSSalesDelivery.EditorID = wLoginUser.ID;
            wWMSSalesDelivery.EditTime = Calendar.getInstance();
            WMSSalesDeliveryDAO.getInstance().UpdatePo(wLoginUser, wWMSSalesDelivery, wErrorCode);

            wResult.AddFaultCode(wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }


    @Override
    public ServiceResult<Integer> WMS_DeleteOutboundOrder(BMSEmployee wLoginUser,
                                                          WMSOutboundOrder wWMSOutboundOrder) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            if (wWMSOutboundOrder == null || wWMSOutboundOrder.ID <= 0  ) {
                wResult.FaultCode = RetCode.SERVER_RST_ERROR_OUT;
                return wResult;
            }
            OutResult<Integer> wErrorCode = new OutResult<>(0);
            wWMSOutboundOrder = WMSOutboundOrderDAO.getInstance().SelectPO(wLoginUser, wWMSOutboundOrder.ID, "", wErrorCode);
            if (wErrorCode.Result != 0) {
                wResult.AddFaultCode(wErrorCode);
                return wResult;
            }
            if (wWMSOutboundOrder == null || wWMSOutboundOrder.ID <= 0) {
                wResult.FaultCode = "待删除单据不存在";
                return wResult;
            }
            wWMSOutboundOrder.ItemList = WMSOutboundOrderItemDAO.getInstance().WMS_SelectOutboundOrderItemList(wLoginUser,
                    wWMSOutboundOrder.ID, Pagination.getMaxSize(), wErrorCode);

            List<Integer> wSalesDeliveryItemIDList = new ArrayList<>();
            List<Integer> wReceiveItemIDList = new ArrayList<>();

            for (WMSOutboundOrderItem wOutboundOrderItem : wWMSOutboundOrder.ItemList) {

                if (wOutboundOrderItem == null || wOutboundOrderItem.ID <= 0 )
                    continue;

                if (wOutboundOrderItem.SalesDeliveryItemID > 0
                        && !wSalesDeliveryItemIDList.contains(wOutboundOrderItem.SalesDeliveryItemID)) {
                    wSalesDeliveryItemIDList.add(wOutboundOrderItem.SalesDeliveryItemID);
                }
                if (wOutboundOrderItem.ReceiveBillItemID > 0
                        && !wReceiveItemIDList.contains(wOutboundOrderItem.ReceiveBillItemID)) {
                    wReceiveItemIDList.add(wOutboundOrderItem.ReceiveBillItemID);
                }
            }

            if (StringUtils.isNotEmpty(wResult.FaultCode)) {
                return wResult;
            }
            WMSOutboundOrderDAO.getInstance().DeletePO(wLoginUser, wWMSOutboundOrder, wErrorCode);

            if (wSalesDeliveryItemIDList.size() > 0) {
                //修改发货单据的发货数
                WMSSalesDeliveryItemDAO.getInstance().WMS_UpdateSalesDeliveryItemFQTY(wLoginUser, wSalesDeliveryItemIDList, wErrorCode);
                wResult.AddFaultCode(wErrorCode);
            }
            if (wReceiveItemIDList.size() > 0) {
                WMSReceiveBillItemDAO.getInstance().WMS_UpdateReceiveBillItemFQTY(wLoginUser, wReceiveItemIDList, wErrorCode);
                wResult.AddFaultCode(wErrorCode);
            }

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }


    @Override
    public ServiceResult<List<WMSOutboundOrder>> WMS_SelectOutboundOrderListBySalesDeliveryID(BMSEmployee wLoginUser, int wSalesDeliveryID, Pagination wPagination) {
        ServiceResult<List<WMSOutboundOrder>> wResult = new ServiceResult<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);
            wResult.Result = WMSOutboundOrderDAO.getInstance().WMS_SelectOutboundOrderList(wLoginUser, wSalesDeliveryID, wPagination, wErrorCode);
            wResult.AddFaultCode(wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSOutboundOrder> WMS_CreateFromReceiveBill(BMSEmployee wLoginUser, WMSReceiveBill wWMSReceiveBill) {
        ServiceResult<WMSOutboundOrder> wResult = new ServiceResult<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);
            wResult.Result = WMSOutboundOrderDAO.getInstance().WMS_CreateFromReceiveBill(wLoginUser, wWMSReceiveBill, wErrorCode);
            wResult.AddFaultCode(wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSOutboundOrder> WMS_CreateFromSalesDelivery(BMSEmployee wLoginUser, WMSSalesDelivery wWMSSalesDelivery) {
        ServiceResult<WMSOutboundOrder> wResult = new ServiceResult<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);
            wResult.Result = WMSOutboundOrderDAO.getInstance().WMS_CreateFromSalesDelivery(wLoginUser, wWMSSalesDelivery, wErrorCode);
            wResult.AddFaultCode(wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSOutboundOrder> WMS_GeneralSubmitStock(BMSEmployee wLoginUser,
                                                                  WMSOutboundOrder wWMSOutboundOrder, int wStatus) {
        ServiceResult<WMSOutboundOrder> wResult = new ServiceResult<>();
        wResult.Result = wWMSOutboundOrder;
        try {
            WMSOutboundOrderStatus wOutboundOrderStatus = WMSOutboundOrderStatus.getEnumType(wStatus);
            if (wWMSOutboundOrder == null || wOutboundOrderStatus == WMSOutboundOrderStatus.Default) {
                wResult.FaultCode = RetCode.SERVER_RST_ERROR_OUT;
                return wResult;
            }

            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wWMSOutboundOrder.ID > 0) {
                List<WMSOutboundOrderItem> wItemList = wWMSOutboundOrder.ItemList;
                wWMSOutboundOrder = WMSOutboundOrderDAO.getInstance().SelectPO(wLoginUser, wWMSOutboundOrder.ID, "", wErrorCode);
                if (wErrorCode.Result != 0) {
                    wResult.AddFaultCode(wErrorCode);
                    return wResult;
                }
                wWMSOutboundOrder.ItemList = wItemList;
                if (wWMSOutboundOrder.ItemList == null || wWMSOutboundOrder.ItemList.size() == 0) {
                    wWMSOutboundOrder.ItemList = WMSOutboundOrderItemDAO.getInstance().WMS_SelectOutboundOrderItemList(wLoginUser,
                            wWMSOutboundOrder.ID, Pagination.getMaxSize(), wErrorCode);

                    if (wErrorCode.Result != 0) {
                        wResult.AddFaultCode(wErrorCode);
                        return wResult;
                    }
                    wWMSOutboundOrder.ItemList.removeIf(p -> p.FQTY <= 0);
                }
            }
            if (wWMSOutboundOrder.ItemList == null || wWMSOutboundOrder.ItemList.size() == 0) {
                wResult.FaultCode = "单据子项不能为空";
                return wResult;
            }

            List<WMSStockOperateRecord> wWMSStockRecordList = new ArrayList<>();

            List<Integer> wSalesDeliveryItemIDList = new ArrayList<>();
            List<Integer> wReceiveItemIDList = new ArrayList<>();
            for (WMSOutboundOrderItem wWMSOutboundOrderItem : wWMSOutboundOrder.ItemList) {
                if (wWMSOutboundOrderItem.StoreStationID <= 0 || wWMSOutboundOrderItem.BatchRecordID <= 0)
                    continue;

                WMSStockOperateRecord wStockOperateRecord = new WMSStockOperateRecord();
                wStockOperateRecord.setStockRecord(wWMSOutboundOrderItem, wWMSOutboundOrder.Type);
                wStockOperateRecord.setUserInfo(wLoginUser);
                wStockOperateRecord.MaterialNum = wWMSOutboundOrderItem.FQTY;
                wStockOperateRecord.RecordType = wWMSOutboundOrder.Type;
                WMSStockRecordOperateDAO.getInstance().WMS_UpdateStockRecordOperate(wLoginUser, wStockOperateRecord, wErrorCode);
                if (wErrorCode.Result != 0) {
                    wResult.AddFaultCode(wErrorCode);
                }
                if (wStockOperateRecord != null && wStockOperateRecord.ID > 0) {
                    wWMSOutboundOrderItem.StockOperateRecordID = wStockOperateRecord.ID;
                    wWMSOutboundOrderItem.StockRecordID = wStockOperateRecord.RecordID;
                }
                if (wWMSOutboundOrderItem.SalesDeliveryItemID > 0
                        && !wSalesDeliveryItemIDList.contains(wWMSOutboundOrderItem.SalesDeliveryItemID)) {
                    wSalesDeliveryItemIDList.add(wWMSOutboundOrderItem.SalesDeliveryItemID);
                }
                if (wWMSOutboundOrderItem.ReceiveBillItemID > 0
                        && !wReceiveItemIDList.contains(wWMSOutboundOrderItem.ReceiveBillItemID)) {
                    wReceiveItemIDList.add(wWMSOutboundOrderItem.ReceiveBillItemID);
                }
                wWMSStockRecordList.add(wStockOperateRecord);
            }
            if (StringUtils.isNotEmpty(wResult.FaultCode)) {
                return wResult;
            }
            wWMSOutboundOrder.Status = wStatus;
            wWMSOutboundOrder.EditTime = Calendar.getInstance();
            wWMSOutboundOrder.EditorID = wLoginUser.ID;
            WMSOutboundOrderDAO.getInstance().UpdatePo(wLoginUser, wWMSOutboundOrder, wErrorCode);

            if (wErrorCode.Result != 0) {
                wResult.AddFaultCode(wErrorCode);
                return wResult;
            }
            wResult.Result = wWMSOutboundOrder;
            if (wWMSOutboundOrder.ID > 0) {
                for (WMSOutboundOrderItem wWMSOutboundOrderItem : wWMSOutboundOrder.ItemList) {
                    wWMSOutboundOrderItem.OutboundOrderID = wWMSOutboundOrder.ID;
                }
                if (wSalesDeliveryItemIDList.size() > 0) {
                    //修改发货单据的发货数
                    WMSSalesDeliveryItemDAO.getInstance().WMS_UpdateSalesDeliveryItemFQTY(wLoginUser, wSalesDeliveryItemIDList, wErrorCode);
                    wResult.AddFaultCode(wErrorCode);
                }
                if (wReceiveItemIDList.size() > 0) {
                    WMSReceiveBillItemDAO.getInstance().WMS_UpdateReceiveBillItemFQTY(wLoginUser, wReceiveItemIDList, wErrorCode);
                    wResult.AddFaultCode(wErrorCode);
                }

                WMSOutboundOrderItemDAO.getInstance().UpdatePoList(wLoginUser,
                        wWMSOutboundOrder.ItemList, wErrorCode);
                wResult.AddFaultCode(wErrorCode);
                wResult.Result = wWMSOutboundOrder;
            }
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }


    @Override
    public ServiceResult<Integer> WMS_UpdateOutboundOrderItem(BMSEmployee wLoginUser,
                                                              WMSOutboundOrderItem wWMSOutboundOrderItem) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            if (wWMSOutboundOrderItem == null ||wWMSOutboundOrderItem.OutboundOrderID <= 0) {
                return wResult;
            }
            OutResult<Integer> wErrorCode = new OutResult<>(0);


            List<Integer> wSalesDeliveryItemIDList = new ArrayList<>();
            List<Integer> wReceiveItemIDList = new ArrayList<>();


            WMSOutboundOrder wWMSOutboundOrder = WMSOutboundOrderDAO.getInstance().SelectPO(wLoginUser, wWMSOutboundOrderItem.OutboundOrderID, "", wErrorCode);
            if (wErrorCode.Result != 0) {
                wResult.AddFaultCode(wErrorCode);
                return wResult;
            }
            if (wWMSOutboundOrder == null || wWMSOutboundOrder.ID <= 0)
                return wResult;


            if (wWMSOutboundOrderItem.StoreStationID > 0 && wWMSOutboundOrderItem.BatchRecordID > 0){
                WMSStockOperateRecord wWMSStockRecord = new WMSStockOperateRecord();
                wWMSStockRecord.setStockRecord(wWMSOutboundOrderItem, wWMSOutboundOrder.Type);
                wWMSStockRecord.setUserInfo(wLoginUser);
                wWMSStockRecord.MaterialNum = wWMSOutboundOrderItem.FQTY;
                wWMSStockRecord.RecordType = wWMSOutboundOrder.Type;
                WMSStockRecordOperateDAO.getInstance().WMS_UpdateStockRecordOperate(wLoginUser, wWMSStockRecord, wErrorCode);
                if (wErrorCode.Result != 0) {
                    wResult.AddFaultCode(wErrorCode);
                    return wResult;
                }
                if (wWMSStockRecord != null && wWMSStockRecord.ID > 0) {
                    wWMSOutboundOrderItem.StockOperateRecordID = wWMSStockRecord.ID;
                    wWMSOutboundOrderItem.StockRecordID = wWMSStockRecord.RecordID;
                }
                if (wWMSOutboundOrderItem.SalesDeliveryItemID > 0
                        && !wSalesDeliveryItemIDList.contains(wWMSOutboundOrderItem.SalesDeliveryItemID)) {
                    wSalesDeliveryItemIDList.add(wWMSOutboundOrderItem.SalesDeliveryItemID);
                }
                if (wWMSOutboundOrderItem.ReceiveBillItemID > 0
                        && !wReceiveItemIDList.contains(wWMSOutboundOrderItem.ReceiveBillItemID)) {
                    wReceiveItemIDList.add(wWMSOutboundOrderItem.ReceiveBillItemID);
                }
            }



            WMSOutboundOrderItemDAO.getInstance().UpdatePo(wLoginUser,
                    wWMSOutboundOrderItem, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

            if (wSalesDeliveryItemIDList.size() > 0) {
                //修改发货单据的发货数
                WMSSalesDeliveryItemDAO.getInstance().WMS_UpdateSalesDeliveryItemFQTY(wLoginUser, wSalesDeliveryItemIDList, wErrorCode);
                wResult.AddFaultCode(wErrorCode);
            }
            if (wReceiveItemIDList.size() > 0) {
                WMSReceiveBillItemDAO.getInstance().WMS_UpdateReceiveBillItemFQTY(wLoginUser, wReceiveItemIDList, wErrorCode);
                wResult.AddFaultCode(wErrorCode);
            }

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_UpdateOutboundOrderItemList(BMSEmployee wLoginUser,
                                                                  List<WMSOutboundOrderItem> wWMSOutboundOrderItemList) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {

            if (wWMSOutboundOrderItemList == null || wWMSOutboundOrderItemList.size() == 0) {
                return wResult;
            }
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSStockOperateRecord> wWMSStockRecordList = new ArrayList<>();

            List<Integer> wSalesDeliveryItemIDList = new ArrayList<>();
            List<Integer> wReceiveItemIDList = new ArrayList<>();

            Map<Integer, WMSOutboundOrder> wOutboundOrderMap = new HashMap<>();
            WMSOutboundOrder wWMSOutboundOrder;

            for (WMSOutboundOrderItem wWMSOutboundOrderItem : wWMSOutboundOrderItemList) {
                if (wWMSOutboundOrderItem.OutboundOrderID <= 0)
                    continue;
                if (!wOutboundOrderMap.containsKey(wWMSOutboundOrderItem.OutboundOrderID)) {
                    wWMSOutboundOrder = WMSOutboundOrderDAO.getInstance().SelectPO(wLoginUser, wWMSOutboundOrderItem.OutboundOrderID, "", wErrorCode);
                    if (wErrorCode.Result != 0) {
                        wResult.AddFaultCode(wErrorCode);
                        continue;
                    }
                    if (wWMSOutboundOrder == null || wWMSOutboundOrder.ID <= 0)
                        continue;
                    wOutboundOrderMap.put(wWMSOutboundOrderItem.OutboundOrderID, wWMSOutboundOrder);
                }
                wWMSOutboundOrder = wOutboundOrderMap.get(wWMSOutboundOrderItem.OutboundOrderID);
                if (wWMSOutboundOrderItem.StoreStationID <= 0 || wWMSOutboundOrderItem.BatchRecordID <= 0)
                    continue;

                WMSStockOperateRecord wWMSStockRecord = new WMSStockOperateRecord();
                wWMSStockRecord.setStockRecord(wWMSOutboundOrderItem, wWMSOutboundOrder.Type);
                wWMSStockRecord.setUserInfo(wLoginUser);
                wWMSStockRecord.MaterialNum = wWMSOutboundOrderItem.FQTY;
                wWMSStockRecord.RecordType = wWMSOutboundOrder.Type;
                WMSStockRecordOperateDAO.getInstance().WMS_UpdateStockRecordOperate(wLoginUser, wWMSStockRecord, wErrorCode);
                if (wErrorCode.Result != 0) {
                    wResult.AddFaultCode(wErrorCode);
                }
                if (wWMSStockRecord != null && wWMSStockRecord.ID > 0) {
                    wWMSOutboundOrderItem.StockOperateRecordID = wWMSStockRecord.ID;
                    wWMSOutboundOrderItem.StockRecordID = wWMSStockRecord.RecordID;
                }
                if (wWMSOutboundOrderItem.SalesDeliveryItemID > 0
                        && !wSalesDeliveryItemIDList.contains(wWMSOutboundOrderItem.SalesDeliveryItemID)) {
                    wSalesDeliveryItemIDList.add(wWMSOutboundOrderItem.SalesDeliveryItemID);
                }
                if (wWMSOutboundOrderItem.ReceiveBillItemID > 0
                        && !wReceiveItemIDList.contains(wWMSOutboundOrderItem.ReceiveBillItemID)) {
                    wReceiveItemIDList.add(wWMSOutboundOrderItem.ReceiveBillItemID);
                }
                wWMSStockRecordList.add(wWMSStockRecord);
            }
            if (StringUtils.isNotEmpty(wResult.FaultCode)) {
                return wResult;
            }



            WMSOutboundOrderItemDAO.getInstance().UpdatePoList(wLoginUser,
                    wWMSOutboundOrderItemList, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

            if (wSalesDeliveryItemIDList.size() > 0) {
                //修改发货单据的发货数
                WMSSalesDeliveryItemDAO.getInstance().WMS_UpdateSalesDeliveryItemFQTY(wLoginUser, wSalesDeliveryItemIDList, wErrorCode);
                wResult.AddFaultCode(wErrorCode);
            }
            if (wReceiveItemIDList.size() > 0) {
                WMSReceiveBillItemDAO.getInstance().WMS_UpdateReceiveBillItemFQTY(wLoginUser, wReceiveItemIDList, wErrorCode);
                wResult.AddFaultCode(wErrorCode);
            }

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }


    @Override
    public ServiceResult<Integer> WMS_DeleteOutboundOrderItem(BMSEmployee wLoginUser,
                                                              WMSOutboundOrderItem wOutboundOrderItem) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            if (wOutboundOrderItem == null ||wOutboundOrderItem.ID<=0|| wOutboundOrderItem.OutboundOrderID <= 0) {
                return wResult;
            }
            OutResult<Integer> wErrorCode = new OutResult<>(0);


            List<Integer> wSalesDeliveryItemIDList = new ArrayList<>();
            List<Integer> wReceiveItemIDList = new ArrayList<>();

            if (wOutboundOrderItem.StockOperateRecordID > 0 ){
                WMSStockRecordOperateDAO.getInstance().WMS_DeleteStockRecordOperate(wLoginUser, wOutboundOrderItem.StockOperateRecordID, wErrorCode);
                if (wErrorCode.Result != 0) {
                    wResult.AddFaultCode(wErrorCode);
                    return wResult;
                }
                if (wOutboundOrderItem.SalesDeliveryItemID > 0
                        && !wSalesDeliveryItemIDList.contains(wOutboundOrderItem.SalesDeliveryItemID)) {
                    wSalesDeliveryItemIDList.add(wOutboundOrderItem.SalesDeliveryItemID);
                }
                if (wOutboundOrderItem.ReceiveBillItemID > 0
                        && !wReceiveItemIDList.contains(wOutboundOrderItem.ReceiveBillItemID)) {
                    wReceiveItemIDList.add(wOutboundOrderItem.ReceiveBillItemID);
                }
            }

            WMSOutboundOrderItemDAO.getInstance().DeletePO(wLoginUser,
                    wOutboundOrderItem, wErrorCode);
            wResult.AddFaultCode(wErrorCode);

            if (wSalesDeliveryItemIDList.size() > 0) {
                //修改发货单据的发货数
                WMSSalesDeliveryItemDAO.getInstance().WMS_UpdateSalesDeliveryItemFQTY(wLoginUser, wSalesDeliveryItemIDList, wErrorCode);
                wResult.AddFaultCode(wErrorCode);
            }
            if (wReceiveItemIDList.size() > 0) {
                WMSReceiveBillItemDAO.getInstance().WMS_UpdateReceiveBillItemFQTY(wLoginUser, wReceiveItemIDList, wErrorCode);
                wResult.AddFaultCode(wErrorCode);
            }

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_DeleteOutboundOrderItemList(BMSEmployee wLoginUser,
                                                                  List<WMSOutboundOrderItem> wWMSOutboundOrderItemList) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            if (wWMSOutboundOrderItemList == null || wWMSOutboundOrderItemList.size() == 0) {
                return wResult;
            }
            OutResult<Integer> wErrorCode = new OutResult<>(0);


            List<Integer> wSalesDeliveryItemIDList = new ArrayList<>();
            List<Integer> wReceiveItemIDList = new ArrayList<>();

            for (WMSOutboundOrderItem wOutboundOrderItem : wWMSOutboundOrderItemList) {

                if (wOutboundOrderItem == null || wOutboundOrderItem.ID <= 0)
                    continue;

                if (wOutboundOrderItem.SalesDeliveryItemID > 0
                        && !wSalesDeliveryItemIDList.contains(wOutboundOrderItem.SalesDeliveryItemID)) {
                    wSalesDeliveryItemIDList.add(wOutboundOrderItem.SalesDeliveryItemID);
                }
                if (wOutboundOrderItem.ReceiveBillItemID > 0
                        && !wReceiveItemIDList.contains(wOutboundOrderItem.ReceiveBillItemID)) {
                    wReceiveItemIDList.add(wOutboundOrderItem.ReceiveBillItemID);
                }
            }
            WMSOutboundOrderItemDAO.getInstance().WMS_DeleteOutboundOrderItemList(wLoginUser, wWMSOutboundOrderItemList, wErrorCode);
            if (StringUtils.isNotEmpty(wResult.FaultCode)) {
                return wResult;
            }

            if (wSalesDeliveryItemIDList.size() > 0) {
                //修改发货单据的发货数
                WMSSalesDeliveryItemDAO.getInstance().WMS_UpdateSalesDeliveryItemFQTY(wLoginUser, wSalesDeliveryItemIDList, wErrorCode);
            }
            if (wReceiveItemIDList.size() > 0) {
                WMSReceiveBillItemDAO.getInstance().WMS_UpdateReceiveBillItemFQTY(wLoginUser, wReceiveItemIDList, wErrorCode);
            }


        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }


    //region 自动创建WMS单据

    // 4 自动创建出库单 按订单创建，一班一条 切换班次自动提交
    // 5 自动创建成品入库单，一班一条，在创建出库单时，将入库单前部提交 单个成品一个批次
    // 6 自动创建出库单，将成品入库明细全部拉出，可人工调整


    //endregion

}
